package zcatt.examples.swt.dnd;

import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.DropTargetListener;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class SimpleDnd {

	Text sourceText;
	Label targetLabel;
	

	public SimpleDnd() {
		// TODO Auto-generated constructor stub
	}

	public static void main(String[] args) {
		Display display = new Display();
		SimpleDnd simple = new SimpleDnd();
		simple.open(display);
		
		display.dispose();
	}

	public void open(Display display)
	{
		Shell shell = new Shell(display);
		shell.setText("SimpleDnd");
		shell.setLayout(new FillLayout());
		Composite sc = new Composite(shell, SWT.BORDER);
		sc.setLayout(new GridLayout(2, true));
		
		
		Group grp;
		
		grp= new Group(sc, SWT.NONE);
		grp.setText("drag source");
		grp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		grp.setLayout(new GridLayout());
		
		sourceText = new Text(grp, SWT.BORDER);
		sourceText.setText("Hello, the world!");
		sourceText.setLayoutData(new GridData(150, SWT.DEFAULT));
		
		Label label;
		label = new Label(grp, SWT.WRAP);
		label.setText("Drag from the above source text to the target label.");
		label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		
		
		grp= new Group(sc, SWT.NONE);
		grp.setText("drag target");
		grp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		grp.setLayout(new GridLayout());
		
		
		targetLabel = new Label(grp, SWT.BORDER);
		targetLabel.setText("Drop here");
		targetLabel.setLayoutData(new GridData(150, SWT.DEFAULT));
		
		
		
		
		//声明drag支持的操作种类, 实际dnd中, 由键盘的ctrl, shift按键确定.
		//不同的operation有不同的mouse cursor指示.
		int dragOperations = DND.DROP_COPY | DND.DROP_MOVE;	
		DragSource dragSrc = new DragSource(sourceText, dragOperations);
		
		//声明drag支持的格式类型. 
		Transfer[] dragTypes = new Transfer[] {TextTransfer.getInstance(),};
		dragSrc.setTransfer(dragTypes);
		
		//3种可能的drag event sequence:
		//	dragStart
		//	dragStart, dragFinished
		//  dragStart, dragSetData*, dragFinished
		dragSrc.addDragListener(new DragSourceListener() {

			@Override
			public void dragStart(DragSourceEvent event) {
				if(sourceText.getText().isEmpty())
				{
					event.doit = false;
				}				
			}

			@Override
			public void dragSetData(DragSourceEvent event) {
				if(TextTransfer.getInstance().isSupportedType(event.dataType))
				{
					event.data = sourceText.getText();
				}				
			}

			@Override
			public void dragFinished(DragSourceEvent event) {
				if(event.detail == DND.DROP_MOVE)
				{
					sourceText.setText("");
				}				
			}
			
		});
		
		//声明drop支持的操作种类, 实际dnd中, 由键盘的ctrl, shift按键确定.
		//不同的operation有不同的mouse cursor指示.
		//DROP_DEFAULT是无按键drop时的操作种类, 由dragEnter()/dragOperationChanged()传入.
		int dropOperations= DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_DEFAULT;	
		DropTarget dropTarget = new DropTarget(targetLabel, dropOperations);
		
		//声明drop支持的格式类型. 
		Transfer[] dropTypes = new Transfer[] {TextTransfer.getInstance(),};
		dropTarget.setTransfer(dropTypes);
		
		//4种可能的drop event sequence,
		//	dragEnter, dragLeave
		//	dragEnter, (dragOver|dragOperationChanged)*, dragLeave
		//	dragEnter, (dragOver|dragOperationChanged)*, dragLeave, dropAccept
		//	dragEnter, (dragOver|dragOperationChanged)*, dragLeave, dropAccept, drop
		dropTarget.addDropListener(new DropTargetListener() {

			@Override
			public void dragEnter(DropTargetEvent event) {
				if(event.detail == DND.DROP_DEFAULT)
				{
					event.detail = DND.DROP_COPY;					
				}				
			}

			@Override
			public void dragLeave(DropTargetEvent event) {			
			}

			//改变按键变换drop operation时出现的回调
			@Override
			public void dragOperationChanged(DropTargetEvent event) {
				if(event.detail == DND.DROP_DEFAULT)
				{
					event.detail = DND.DROP_COPY;					
				}				
			}

			@Override
			public void dragOver(DropTargetEvent event) {
				event.feedback = DND.FEEDBACK_SELECT |DND.FEEDBACK_SCROLL;
				if(TextTransfer.getInstance().isSupportedType(event.currentDataType))
				{
					//其它判据决定event.detail
				}
				else
				{
					event.detail = DND.DROP_NONE;	//指示不可drop
				}
				
			}

			@Override
			public void drop(DropTargetEvent event) {
				if(TextTransfer.getInstance().isSupportedType(event.currentDataType))
				{
					String text = (String)event.data;
					targetLabel.setText(text);
				}
			}

			@Override
			public void dropAccept(DropTargetEvent event) {
			}			
		});
		
		
		
		shell.setSize(600, 400);
		shell.open();
		
		while(!shell.isDisposed())
		{
			if(!display.readAndDispatch())
				display.sleep();
		}
		
	}
}
